package sample.pim;

import java.util.*;
import java.io.*;
import javax.microedition.io.*;

/**
 * This class provides J2ME client access to J2EE services. It is created
 * by a code-generator; you should note that any changes you make will
 * be lost if you re-generate the code.
 *
 * The methods in this class are not thread-safe.
 */

public class PdapMobileClient {
    
    /** The URL of the servlet gateway */
    private String serverURL;
    
    /** The session cookie of this client */
    private String sessionCookie;
    
    
    
    /**
     * Constructs a new PdapMobileClient
     * and initializes the URL to the servlet gateway from a hard-coded value.
     */
    public PdapMobileClient() {
        //this("http://localhost:8084/GContactsServlet/servlet/pdapcontactsservice.PdapMobileServlet");
        this("http://8.17.169.12:8030/GContactsServlet/servlet/pdapcontactsservice.PdapMobileServlet");
    }
    
    /**
     * Constructs a new PdapMobileClient
     * and initializes the URL to the servlet gateway from the given value
     *
     * @param serverURL URL of the deployed servlet
     */
    public PdapMobileClient(String serverURL) {
        this.serverURL = serverURL;
    }
    public String testoperation(String[] s) throws IOException {
        Object[] args = new Object[] {
            s
        };
        return (String) invokeServer(1, args);
    }
    
    
    /**
     *  This method performes a dynamic invocation on the server. It is generic in
     *  order to reduce the code size.
     *
     *@param  requestID        The id of the server service (method) we wish to
     *      invoke.
     *@param  parameters       The parameters that should be passed to the server
     *      (type safety is not checked by this method!)
     *@param  returnType       Is used to indicate the return type we should read
     *      from the server
     *@return                  The return value from the invoked service
     *@exception  IOException  When a communication error or a remove exception
     * occurs
     */
    private Object invokeServer(int requestID, Object[] parameters) throws IOException {
        HttpConnection connection = (HttpConnection) Connector.open( serverURL );
        connection.setRequestMethod(HttpConnection.POST);
        connection.setRequestProperty("Content-Type", "application/octet-stream");
        connection.setRequestProperty("Accept", "application/octet-stream");
        
        if (sessionCookie == null) {
            // if this is the first time this client contatcs the server,
            // verify that the version matches
            connection.setRequestProperty("version", "11-Oct-2008/00:26:02-BDT");
        } else {
            connection.setRequestProperty("cookie", sessionCookie);
        }
        
        DataOutputStream output = connection.openDataOutputStream();
        
        writeObject(output, this);
        
        /* Write the byte signifying that only one call
         * is being made.
         */
        output.writeShort(1 /* one call to be made to the server */);
        
        output.writeInt(requestID);
        for (int i = 0; i < parameters.length; i++ ) {
            writeObject(output, parameters[i]);
        }
        
        output.close();
        
        int response;
        try {
            response = connection.getResponseCode();
        } catch (IOException e) {
            throw new IOException("No response from " + serverURL);
        }
        if (response != 200) {
            throw new IOException(response + " " + connection.getResponseMessage());
        }
        DataInputStream input = connection.openDataInputStream();
        String sc = connection.getHeaderField("set-cookie");
        if (sc != null) {
            sessionCookie = sc;
        }
        short errorCode = input.readShort();
        if (errorCode != 1) {
            // there was a remote exception
            throw new IOException((String) readObject(input));
        }
        
        Object returnValue = readObject(input);
        
        input.close();
        connection.close();
        return returnValue;
    }
    
    private void writeObject(DataOutputStream out, Object o) throws IOException {
        if (o == this) {
            out.writeShort(1 /* invocation code */);
        } else if (o == null) {
            out.writeShort(-1);
        } else if (o.getClass().isArray()) {
            out.writeShort(-2 /* ARRAY TYPE */);
            Object[] array = (Object[]) o;
            out.writeShort(7 /* STRING_TYPE */);
            out.writeInt(array.length);
            for (int i = 0; i < array.length; i++) {
                writeObject(out, array[i]);
            }
        } else if (o instanceof String) {
            out.writeShort(7 /* STRING_TYPE */);
            out.writeUTF((String) (String) o);
        } else {
            // default if a data type is not supported
            throw new IllegalArgumentException(
                "Unsupported parameter type: " + o.getClass());
        }
    }
    
    private static Object readObject(DataInput in) throws IOException {
        int type = in.readShort();
        int length;
        switch (type) {
            case 7 /* STRING_TYPE */:
                return in.readUTF();
            case -2: { /* ARRAY */
                short elementType = in.readShort();
                length = in.readInt();
                switch (elementType) {
                }
            }
            case -1: /* NULL */
                return null;
        }
        throw new IllegalArgumentException("Unsupported return type (" + type + ")");
    }
}
